using System;
using System.Collections.Generic;
using Unity.Entities;
using UnityEngine;

namespace Gj
{
    public class OverlayService : GameService
    {
        public static OverlayService single;
        private GameObject _body;
        private Camera _camera;
        private Action<string, OverlayItem> _click;

        private Func<OverlayItem, bool> _filter;
        private OverlayItem _item;
        private List<OverlayItem> overlayItemList;

        private Dictionary<string, Queue<OverlayText>> overlayTextList;
        private bool show;

        static OverlayService()
        {
            single = new OverlayService();
        }

        public void OnInit()
        {
            overlayItemList = new List<OverlayItem>();
            overlayTextList = new Dictionary<string, Queue<OverlayText>>();
        }

        public void OnDestroy()
        {
            single = new OverlayService();
        }

        public void OnUpdate()
        {
            foreach (var overlayItem in overlayItemList)
            {
                if (!overlayItem.show) continue;
                Update(overlayItem);
            }
            // if (_filter == null)
            // {
            // 	foreach (var overlayItem in overlayItemList)
            // 	{
            // 		if (!overlayItem.show) continue;
            // 		UpdateItem(overlayItem);
            // 	}
            // }
            // else 
            // {
            // 	foreach (var overlayItem in overlayItemList)
            // 	{
            // 		if (!overlayItem.filter) continue;
            // 		UpdateItem(overlayItem);
            // 	}
            // }
        }

        public void SetClick(Action<string, OverlayItem> cb)
        {
            _click = cb;
        }

        // public void SetFilter(Func<OverlayItem, bool> f)
        // {
        // 	_filter = f;
        // 	if (_filter == null)
        // 	{
        // 		foreach (var overlayItem in overlayItemList)
        // 		{
        // 			overlayItem.gameObject.SetActive(overlayItem.show);
        // 			overlayItem.Filter(false);
        // 		}
        // 	}
        // 	else
        // 	{
        // 		foreach (var overlayItem in overlayItemList)
        // 		{
        // 			overlayItem.Filter(_filter(overlayItem));
        // 			overlayItem.gameObject.SetActive(overlayItem.filter);
        // 		}
        // 	}
        // }

        public void Show(OverlayItem item)
        {
            item.Show();
        }

        public void Hide(OverlayItem item)
        {
            item.Hide();
        }

        public void Update(OverlayItem item)
        {
            item.Refresh(_camera);
        }

        /*public void SetLevel(int s)
        {
            level = s;
            foreach (var overlayItem in overlayItemList)
            {
                overlayItem.SetLevel(level);
            }
        }*/

        public void SetCanvasAndCamera(GameObject body, Camera camera)
        {
            _body = body;
            _camera = camera;
        }

        public void OnClick(string key, OverlayItem item)
        {
            if (_click != null) _click(key, item);
            if (_item != null && _item != item) _item.Cancel();
            OnSelect(item);
            _item = item;
        }

        public void OnRefresh(OverlayItem item)
        {
            Update(item);
        }

        public void OnSelect(OverlayItem item)
        {
            item.transform.SetParent(null);
            item.transform.SetParent(_body.transform);
        }

        public void CancelSelect()
        {
            if (_item != null) _item.Cancel();
        }

        public void OpenOverlayItem(string type, ref OverlayItem item, Element element)
        {
            if (item == null)
            {
                item = ObjectService.single.GetObj("Base", string.Format("Overlay/Item/{0}", type))
                    .GetComponent<OverlayItem>();
                item.transform.SetParent(_body.transform);
                item.transform.localScale = Vector3.one;
            }

            // item.Hide();
            // item.Filter(false);
            item.element = element;
            item.Show();
            overlayItemList.Add(item);
            // if (_filter != null)
            // {
            // 	item.Filter(_filter(item));
            // 	if (item.filter)
            // 	{
            // 		UpdateItem(item);
            // 		item.gameObject.SetActive(true);
            // 	}
            // }
        }

        public void CloseOverlayItem(OverlayItem item)
        {
            if (item == null) return;
            item.Hide();
            overlayItemList.Remove(item);
            for (var i = 0; i < item.list.Count; i++)
            {
                item.list[i].item = null;
                item.list[i].transform.SetParent(_body.transform);
            }

            item.list.Clear();
        }

        public void ApplyOverlayText(string type, OverlayItem item, Action<OverlayText> cb)
        {
            if (item == null) return;
            if (!item.show) return;
            OverlayText text = null;
            if (overlayTextList.ContainsKey(type) && overlayTextList[type].Count > 0)
                text = overlayTextList[type].Dequeue();
            if (text == null)
            {
                text = ObjectService.single.GetObj("Base", string.Format("Overlay/Text/{0}", type))
                    .GetComponent<OverlayText>();
                text.type = type;
            }

            text.transform.SetParent(item.transform);
            text.item = item;
            item.list.Add(text);
            text.gameObject.SetActive(true);
            text.transform.localScale = Vector3.one;
            text.transform.localPosition = Vector3.zero;

            cb(text);
        }

        public void ReturnOverlayText(OverlayText text)
        {
            if (text.item != null) text.item.list.Remove(text);
            text.transform.SetParent(_body.transform);
            text.gameObject.SetActive(false);
            if (!overlayTextList.ContainsKey(text.type)) overlayTextList.Add(text.type, new Queue<OverlayText>());
            overlayTextList[text.type].Enqueue(text);
        }
    }
}